﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using MVVMComun;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using Windows.UI.Xaml.Controls;
using System.Net.Http;
using Windows.Storage.Streams;
using Windows.Networking.Connectivity;



namespace GuiaCiudad.ViewModel
{
   public class GuiaCiudadViewModel:NotificationObject  
    {
        GuiaCiudadModel GCM;

        private ObservableCollection<Foto> fotos;
        public ObservableCollection<Foto> Fotos  
        {
            get { return fotos; }
            set { fotos = value;
                OnPropertyChanged(this);
            }
        }

        private ObservableCollection<Noticia> noticias;
        public ObservableCollection<Noticia> Noticias
        {
            get { return noticias; }
            set { noticias = value;
                  OnPropertyChanged(this);
            }
        }

        private ObservableCollection<Pronostico> pronosticos;
        public ObservableCollection<Pronostico> Pronosticos
        {
            get { return pronosticos; }
            set { pronosticos = value;
                    OnPropertyChanged(this);
            }
        }

        private ActionComand saveCommand;

        public ActionComand SaveCommand
        {
            get {

                if (saveCommand == null)
                    saveCommand = new ActionComand(new Action(guardar));
                return   saveCommand; 
            
            }
           
        }


        private string ciudad;

        public string Ciudad
        {
            get { return ciudad; }
            set { ciudad = value;
            OnPropertyChanged(this);
            }
        }

        private string pais;

        public string Pais
        {
            get { return pais; }
            set { pais = value;
            OnPropertyChanged(this);
            }
        }
        
        


        public GuiaCiudadViewModel()
        {
            
            Fotos = new ObservableCollection<Foto>();
            ConfigModels();
            LoadSettings();
            LoadOffline();  
            var cp = NetworkInformation.GetConnectionProfiles()[0].GetNetworkConnectivityLevel();
            if(cp.Equals(NetworkConnectivityLevel.InternetAccess)){
             
            }else{
            configServices();
            cargarDatos();
        }
           
        }

        private  async Task LoadOffline()
        {

            try
            {

                var localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
                var folderToSave = await localfolder.CreateFolderAsync("Noticias", Windows.Storage.CreationCollisionOption.OpenIfExists);
                var file = await folderToSave.GetFileAsync("Noticias.dat");
                DataContractSerializer ds = new DataContractSerializer(new List<Noticia>().GetType());
                var stream = await file.OpenStreamForReadAsync();
                var resultN = ds.ReadObject(stream) as List<Noticia>;
                stream.Dispose();
                Noticias = new ObservableCollection<Noticia>(resultN);

            }
            catch (Exception e)
            {
                
                throw;
            }


            try
            {
              var  localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
             var   folderToSave = await localfolder.CreateFolderAsync("Pronosticos", Windows.Storage.CreationCollisionOption.OpenIfExists);
              var  file = await folderToSave.GetFileAsync("Pronosticos.dat");
                var  ds = new DataContractSerializer(new List<Pronostico>().GetType());
                var stream = await file.OpenStreamForReadAsync();
                var resultP = ds.ReadObject(stream) as List<Pronostico>;
                Pronosticos = new ObservableCollection<Pronostico>(resultP);
                stream.Dispose();
            }
            catch (Exception e)
            {
                
                throw;
            }
            try
            {
             var   localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
             var   folderToSave = await localfolder.CreateFolderAsync("Fotos", Windows.Storage.CreationCollisionOption.OpenIfExists);
              var  file = await folderToSave.GetFileAsync("fotos.dat");
               var ds = new DataContractSerializer(new List<Foto>().GetType());
              var  stream = await file.OpenStreamForReadAsync();
                var resultF = ds.ReadObject(stream) as List<Foto>;

                foreach (Foto f in resultF)
                {
                    file = await folderToSave.GetFileAsync(f.Id + ".jpg");
                    var stream2 = await file.OpenStreamForReadAsync();
                    Windows.UI.Xaml.Media.Imaging.BitmapImage Bi = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                    await Bi.SetSourceAsync((IRandomAccessStream)stream2.AsInputStream());
                    f.BitmapImageSource = Bi;
                }

                stream.Dispose();
                Fotos = new ObservableCollection<Foto>(resultF);
            }
            catch (Exception e)
            {
                
                throw;
            }
  
        }

        private async void LoadSettings()
        {

            Windows.Storage.StorageFolder localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;

            var folderToSave = await localfolder.CreateFolderAsync("Settings", Windows.Storage.CreationCollisionOption.OpenIfExists);
            Windows.Storage.StorageFile file;
            try
            {
                 file = await folderToSave.GetFileAsync("Ubicacion.dat");

            }
            catch (Exception)
            {
                file = null;
                
            }
            if (file != null)
            {
                var stream = await file.OpenStreamForReadAsync();
                StreamReader reader = new StreamReader(stream);
                var country = reader.ReadLine();
                var city = reader.ReadLine();

                if ((city != null && country != null))
                {
                    GCM.Pais = country;
                    GCM.Ciudad = city;
                }
                reader.Dispose();
            }
            
            Ciudad = GCM.Ciudad;
            Pais = GCM.Pais;
            GCM.WeatherS.Pais = Pais;
            GCM.WeatherS.Ciudad = Ciudad;
          
        }

        private async void  UpdateSettings() 
        {
            Windows.Storage.StorageFolder localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            
            var folderToSave = await localfolder.CreateFolderAsync("Settings", Windows.Storage.CreationCollisionOption.OpenIfExists);
            var file = await folderToSave.CreateFileAsync("Ubicacion.dat", Windows.Storage.CreationCollisionOption.ReplaceExisting);
            var stream = await file.OpenStreamForWriteAsync();
            StreamWriter writer = new StreamWriter(stream);
            writer.WriteLine((Pais));
            writer.WriteLine((Ciudad));
            writer.Dispose();      
        }

        private async void  configServices()
        {
            GCM.FlickerS.FlickerServiceResponseReady += (s, e) => {
          
               if(e.Result.Count>10)
                e.Result.RemoveRange(9, e.Result.Count - 10);
              
                var a=   pesistObjectFotos(e.Result, "Fotos", "fotos.dat");
        
            };


            GCM.BingS.BingNewsServiceResponseReady += (s, e) =>
            {

                Noticias = new ObservableCollection<Noticia>(e.Result);

                var a = pesistObjectGenerico(e.Result, "Noticias", "Noticias.dat", e.Result.GetType());

            };

            GCM.WeatherS.WeatherResponseReady += (s, e) =>
            {
                Pronosticos = new ObservableCollection<Pronostico>(e.Result);
                var a =  pesistObjectGenerico(e.Result, "Pronosticos", "Pronosticos.dat", e.Result.GetType());
            };

        }

        private async Task<int> pesistFoto(Foto o,string folder,string name) {

            try
            {

                var localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
                if (folder != string.Empty)
                {
                    var folderToSave = await localfolder.CreateFolderAsync(folder, Windows.Storage.CreationCollisionOption.OpenIfExists);
                    var file = await folderToSave.CreateFileAsync(name, Windows.Storage.CreationCollisionOption.ReplaceExisting);
                    var stream = await file.OpenStreamForWriteAsync();
                   try{
                    HttpClient wc = new HttpClient();
                    var foto = await wc.GetStreamAsync(o.Url);
                    await foto.CopyToAsync(stream);
                    stream.Flush();
                    stream.Dispose();
                    stream = await file.OpenStreamForReadAsync();
                     Windows.UI.Xaml.Media.Imaging.BitmapImage Bi = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
                    Bi.SetSource((IRandomAccessStream)stream.AsInputStream());
                    o.BitmapImageSource = Bi;
                    stream.Dispose();
                     }
                   catch (Exception ex)
                   {
                            
                            
                   }

                }
            }
            catch (Exception e)
            {
                
                
            }
               return 0;
 
        }



        private async Task<int> pesistObjectFotos(List<Foto> o, string folder, string name)
        { 

            var localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            if (folder != string.Empty)
            {
                var folderToSave = await localfolder.CreateFolderAsync(folder, Windows.Storage.CreationCollisionOption.OpenIfExists);


                var file = await folderToSave.CreateFileAsync(name, Windows.Storage.CreationCollisionOption.ReplaceExisting);

                var stream = await file.OpenStreamForWriteAsync();

                DataContractSerializer ds = new DataContractSerializer(o.GetType());
                ds.WriteObject(stream,o);
                stream.Dispose();
            


            foreach (Foto f in o) {
                try
                {
                    await pesistFoto(f, "Fotos", f.Id + ".jpg");
             
                }
                catch(Exception e) { 
                
                }
            }
            }
            Fotos = new ObservableCollection<Foto>(o);
            return 0;
        }


        private async Task<int> pesistObjectGenerico(object o, string folder, string name, Type type)
        {

            var localfolder = Windows.Storage.ApplicationData.Current.LocalFolder;
            if (folder != string.Empty)
            {
               
                var folderToSave = await localfolder.CreateFolderAsync(folder, Windows.Storage.CreationCollisionOption.OpenIfExists);
              
                var file = await folderToSave.CreateFileAsync(name, Windows.Storage.CreationCollisionOption.ReplaceExisting);

                var stream = await file.OpenStreamForWriteAsync();

                DataContractSerializer ds = new DataContractSerializer(type);
                ds.WriteObject(stream, o);
                stream.Dispose();
            }
            return 0;
        }

        

        private void cargarDatos()
        {
           // GCM.FlickerS.Size = "s";
            GCM.FlickerS.getFotos(GCM.Ciudad);
            GCM.BingS.getNoticias(GCM.Ciudad);
            GCM.WeatherS.getForeCast();

        }

        private void ConfigModels()
        {
            GCM = new GuiaCiudadModel();
        }

        private void guardar() {

            var cp = NetworkInformation.GetConnectionProfiles()[0].GetNetworkConnectivityLevel();
            
         //   if(cp.Equals(NetworkConnectivityLevel.InternetAccess)){
            if(true){
                if (Ciudad != GCM.Ciudad)
             {
                    UpdateSettings();
                    GCM.Pais = Pais;
                    GCM.Ciudad = Ciudad;
                    GCM.WeatherS.Pais = Pais;
                    GCM.WeatherS.Ciudad = Ciudad;
                    configServices();
                    cargarDatos();

                }
            
            }
     
        
        } 
   
   }

    

}
